#include "app_function.h"
#include "driver_function.h"
#include "lfs.h"
#include "lvgl.h"
#include "stdlib/lv_mem.h"

const struct lfs_config w25Q64_cfg = {
    // block device operations
    .read  = driver_flash_littlefs_read,
    .prog  = driver_flash_littlefs_prog,
    .erase = driver_flash_littlefs_erase,
    .sync  = driver_flash_littlefs_sync,

    // block device configuration
    .read_size      = 256,
    .prog_size      = 256,
    .block_size     = 4096,
    .block_count    = 2048,
    .cache_size     = 256,
    .lookahead_size = 32,
    .block_cycles   = 500,
};

const struct lfs_config w25Q128_cfg = {
    // block device operations
    .read  = driver_flash_littlefs_read,
    .prog  = driver_flash_littlefs_prog,
    .erase = driver_flash_littlefs_erase,
    .sync  = driver_flash_littlefs_sync,

    // block device configuration
    .read_size      = 256,
    .prog_size      = 256,
    .block_size     = 4096,
    .block_count    = 4096,
    .cache_size     = 256,
    .lookahead_size = 64,
    .block_cycles   = 500,
};

lfs_t app_littlefs_lfs;
void app_littlefs_init()
{
    uint16_t flash_id = 0;
    const struct lfs_config *cfg_ptr = NULL;
    lfs_dir_t lvgl_root_dir;
    int lvgl_root_dir_err;

    driver_flash_init(); //init spi falsh

    flash_id = driver_flash_read_id();
    switch (flash_id) {
    case FLASH_W25Q64_ID: //64Mbit = 64/8 = 8MByte
        cfg_ptr = &w25Q64_cfg;
        break;
    case FLASH_W25Q128_ID:
        cfg_ptr = &w25Q128_cfg;
        break;
    }
    driver_flash_set_size(flash_id);

    int err = lfs_mount(&app_littlefs_lfs, cfg_ptr);
    if (err) {
        lfs_format(&app_littlefs_lfs, cfg_ptr);
        lfs_mount(&app_littlefs_lfs, cfg_ptr);
    }
    lv_littlefs_set_handler(&app_littlefs_lfs);


    // Create dir /lvgl for lv_conf.h LV_FS_LITTLEFS_PATH
    lvgl_root_dir_err = lfs_dir_open(&app_littlefs_lfs, &lvgl_root_dir, LV_FS_LITTLEFS_PATH);
    if (lvgl_root_dir_err == LFS_ERR_OK) {
        lfs_dir_close(&app_littlefs_lfs, &lvgl_root_dir); //close the open dir
        return;
    } else {
        printf("Directory %s does not exist. Attempting to create...\r\n", LV_FS_LITTLEFS_PATH);
        lvgl_root_dir_err = lfs_mkdir(&app_littlefs_lfs, LV_FS_LITTLEFS_PATH);
        if(LFS_ERR_OK != lvgl_root_dir_err){
            printf("Failed to create directory %s, LittleFS error: %d\n", LV_FS_LITTLEFS_PATH, err);
        }
    }
}
